

bitmap2gcode.prototype.processDotSimulation = function (gCode) {
    gCode.setDotMode(this.gcodeParams.dotTime); // 设置点雕刻时间
    this.gCode.initialise();
    let ratioLaser = this.gcodeParams.laserPowerMaxS / 255; // 计算激光器功率比例

    let positionCount = 0; // 计数直
    let lineCount = 0; // 累积行数
    for (let y = 0; y < this.height; y++) {
    // for (let y = this.height - 1; y >= 0; y--) {
        for (let x = 0; x < this.width; x++) {  // 遍历每一个像素点
            let grayscale = this.data[x][y]; // 获取灰度值
            // 在打点模式下，每一个像素点都需要检测激光打点 
            if (grayscale < 255) { // 说明该点要打
                if (lineCount > 0) { // 
                    gCode.moveLineY(lineCount, positionCount);
                    positionCount = 0;
                    lineCount = 0;
                }
                if (positionCount > 0 ) { // 如果有计数直 （即上一个功率值需要移动 positionCount 个像素点）
                    gCode.movePixelsX(positionCount);
                    positionCount = 0; // 移动完计数直归零
                }
                let powerValue = Math.floor(ratioLaser * (255 - grayscale) ); // 计算新的激光器激光功率
                // gCode.setLaserOnS(powerValue); // 设置新的激光器激光功率
                gCode.setLaserOnS(powerValue); // 设置新的激光器激光功率
                gCode.movePixelsX(1);
                // gCode.turnLaserOff(); // 关闭激光
                gCode.setLaserOnS(0); 
            }else{ 
                positionCount++; // 计数直
            }
        }
        // 一行扫描完成，移动到新一行
        positionCount = 0;
        lineCount++;
    }
    gCode.finishProgram();
}
bitmap2gcode.prototype.processDot = function (gCode) {
    gCode.setDotMode(this.gcodeParams.dotTime); // 设置点雕刻时间
    this.gCode.initialise();
    // let ratioLaser = this.gcodeParams.laserPowerMaxS / 255; // 计算激光器功率比例

    let positionCount = 0; // 计数直
    let lineCount = 0; // 累积行数
    for (let y = 0; y < this.height; y++) {
        for (let x = 0; x < this.width; x++) {  // 遍历每一个像素点
            let grayscale = this.data[x][y]; // 获取灰度值
            positionCount++; // 计数直
            // 在打点模式下，每一个像素点都需要检测激光打点 
            if (grayscale < 255) { // 说明该点要打
                if (lineCount > 0) { // 
                    gCode.moveLineY(lineCount, positionCount, true);
                    positionCount = 0;
                    lineCount = 0;
                }
                // if (positionCount > 0 ) { // 快速跳转n个点
                gCode.dotMove(positionCount);
                positionCount = 0; // 移动完计数直归零
                // }
                // gCode.dotMove(1);
            }
        }
        // 一行扫描完成，移动到新一行
        positionCount = 0;
        lineCount++;
    }
    gCode.finishProgram();
}

stucki = function (data, w, h, threshold) {
    for (let i = 0; i < w; i++) {
        for (let j = 0; j < h; j++) {
            let value = data[i][j] < threshold ? 0 : 255;
            let error = Math.floor((data[i][j] - value) / 42);
            let error2 = error << 1;
            let error4 = error << 2;
            let error8 = error << 3;

            data[i][j] = value;

            if (j < h - 1) data[i][j + 1] += error8;
            if (j < h - 2) data[i][j + 2] += error4;

            if (i < w - 1) {
                if (j >= 2) data[i + 1][j - 2] += error2;
                if (j >= 1) data[i + 1][j - 1] += error4;
                data[i + 1][j] += error8;
                if (j < h - 1) data[i + 1][j + 1] += error4;
                if (j < h - 2) data[i + 1][j + 2] += error2;
            }
            if (i < w - 2) {
                if (j >= 2) data[i + 1][j - 2] += error;
                if (j >= 1) data[i + 1][j - 1] += error2;
                data[i + 1][j] += error4;
                if (j < h - 1) data[i + 1][j + 1] += error2;
                if (j < h - 2) data[i + 1][j + 2] += error;
            }
        }
    }
}

sierra3 = function (data, w, h, threshold) {
    for (let i = 0; i < w; i++) {
        for (let j = 0; j < h; j++) {
            let value = data[i][j] < threshold ? 0 : 255;
            let error = Math.floor((data[i][j] - value) / 32);

            data[i][j] = value;

            if (j < h - 1) data[i][j + 1] += error * 5;
            if (j < h - 2) data[i][j + 2] += error * 3;

            if (i < w - 1) {
                if (j >= 2) data[i + 1][j - 2] += error * 2;
                if (j >= 1) data[i + 1][j - 1] += error * 4;
                data[i + 1][j] += error * 5;
                if (j < h - 1) data[i + 1][j + 1] += error * 4;
                if (j < h - 2) data[i + 1][j + 2] += error * 2;
            }
            if (i < w - 2) {
                if (j >= 1) data[i + 2][j - 1] += error * 2;
                data[i + 2][j] += error * 3;
                if (j < h - 1) data[i + 2][j + 1] += error * 2;
            }
        }
    }
}

floydsteinberg = function (data, w, h, threshold) {
    for (let i = 0; i < w; i++) {
        for (let j = 0; j < h; j++) {
            let value = data[i][j] < threshold ? 0 : 255;
            let error = Math.floor((data[i][j] - value) / 16);
            data[i][j] = value;

            if (j < h - 1) data[i][j + 1] += error * 7;

            if (i < w - 1) {
                if (j >= 1) data[i + 1][j - 1] += error * 3;
                data[i + 1][j] += error * 5;
                if (j < h - 1) data[i + 1][j + 1] += error * 1;
            }
        }
    }
}

create_curve = function (RiemersmaCurve, width, height, create_dim) {
    let iterations = -1;
    for (let j = 0; j < 20; j++) { // 迭代次数最多设置为 20
        create_dim = Math.round(Math.pow(2, j + 1));
        if (create_dim > width && create_dim > height) {
            iterations = j;
            break;
        }
    }
    if (iterations === -1) {
        console.log("create_dim is too small, please increase it");
        return;
    }
    let rule_len;
}

hilbert_mod_curve = function (data, w, h, threshold, use_riemersma = true) {
    let max = 16;
    let err_len = use_riemersma ? 16 : 8;
    let q_err = new Array(err_len);
    let weights = new Array(err_len);
    if (use_riemersma) {
        let m = Math.exp(Math.log(max / (err_len - 1)));
        let v = 1.0;
        for (let i = 0; i < err_len; i++) {
            Weights[i] = Math.round(v);
            v *= m;
        }
    } else { //  modified riemersma algorithm
        let weights_sum = 0.0;
        for (let i = 0; i < err_len; i++) {
            let w = Math.pow(2, (i / err_len) * 10.0) / 1000.0 * max;
            weights[i] = w;
            weights_sum += w;
        }
        for (let i = 0; i < err_len; i++) {
            weights[i] /= weights_sum;
        }
    }
    // generate the hilbert curve
    let curve_dim;
}


graySelf(gray) {
    const src = cv.imread(this._originalElement)
    // const gray = new cv.Mat()
    gray = new cv.Mat(src.rows, src.cols, cv.CV_8UC4)
    // gray = src.clone()

    // 检查是否是4通道图像（RGBA）
    if (src.type() === cv.CV_8UC4) {
      // 分离RGBA通道
      const rgbaPlanes = new cv.MatVector();
      cv.split(src, rgbaPlanes);
      
      // 获取各通道
      const R = rgbaPlanes.get(0);
      const G = rgbaPlanes.get(1);
      const B = rgbaPlanes.get(2);
      const A = rgbaPlanes.get(3);
      
      // 使用标准灰度公式直接计算
      for (let i = 0; i < src.rows; i++) {
        for (let j = 0; j < src.cols; j++) {
          // 获取各通道值
          const r = R.ucharPtr(i, j)[0];
          const g = G.ucharPtr(i, j)[0];
          const b = B.ucharPtr(i, j)[0];
          // const a = A.ucharPtr(i, j)[0] / 255.0; // 归一化透明度
          const a = A.ucharPtr(i, j)[0]; // 
          
          // 标准灰度公式: 0.299*R + 0.587*G + 0.114*B
          let grayValue = 0.299 * r + 0.587 * g + 0.114 * b;
          // let grayValue = 0.299 * R.ucharPtr(i, j)[0] + 0.587 * G.ucharPtr(i, j)[0] + 0.114 * B.ucharPtr(i, j)[0];
          
          // 应用透明度（可选）
          // grayValue = grayValue * a;
          
          // 设置灰度值
          if (this.invert){
            gray.ucharPtr(i, j)[0] = Math.round(255 - grayValue);
            gray.ucharPtr(i, j)[1] = Math.round(255 - grayValue);
            gray.ucharPtr(i, j)[2] = Math.round(255 - grayValue);
            gray.ucharPtr(i, j)[3] = a; // 保留透明度设置
          }else{
            gray.ucharPtr(i, j)[0] = Math.round(grayValue);
            gray.ucharPtr(i, j)[1] = Math.round(grayValue);
            gray.ucharPtr(i, j)[2] = Math.round(grayValue);
            gray.ucharPtr(i, j)[3] = a; // 保留透明度设置
          }
        }
      }
      // 释放内存
      rgbaPlanes.delete();
      R.delete();
      G.delete();
      B.delete();
      A.delete();
    } else {
      // 如果不是4通道图像，直接转换
      cv.cvtColor(src, gray, cv.COLOR_RGB2GRAY);
    }
    src.delete();
    // if (this.invert) {
    //   cv.bitwise_not(gray, gray)
    // }
    return gray
  },